/*
 *  XMLNode.cpp
 *  cactus-xml
 *
 *  Created by Yury Nikalayuk on 02.04.10.
 *  Copyright 2011 CactusSoft. All rights reserved.
 *
 */

#include "XMLNode.h"
#include <sstream>

XMLValue::XMLValue()
{
}

XMLValue::XMLValue(const std::string &_value):
value(_value)
{
}

const std::string & XMLValue::AsString() const
{
	return value;
}

int XMLValue::AsInt(int defaultValue /*=0*/) const
{
	if(value.empty())
		return defaultValue;
	
	std::istringstream str(value);
	int result;
	str >> result;
	return result;
}

double XMLValue::AsDouble(double defaultValue /*=0*/) const
{
	if(value.empty())
		return defaultValue;
	
	std::istringstream str(value);
	double result;
	str >> result;
	return result;
}

bool XMLValue::AsBool(bool defaultValue /*= false*/) const
{
	if(value == "true")
		return true;
	else if(value == "false")
		return false;
	else
		return defaultValue;
}

XMLNode::XMLNode():
value("")
{
}

XMLNode::~XMLNode()
{
	for(XMLNodes::iterator it = children.begin(); it != children.end(); it++)
		delete *it;
	children.clear();
	childrenMap.clear();
}

XMLNode::XMLNode(const XMLNode &node):
value(node.value)
{
}

const std::string & XMLNode::Name() const
{
	return name;
}

const XMLValue & XMLNode::Value() const
{
	return value;
}

int XMLNode::IntValue(int defaultValue /*= 0*/) const
{
	return value.AsInt(defaultValue);
}

double XMLNode::DoubleValue(double defaultValue /*= 0*/) const
{
	return value.AsDouble(defaultValue);
}

bool XMLNode::BoolValue(bool defaultValue /*= false*/) const
{
	return value.AsBool(defaultValue);
}

const std::string & XMLNode::StringValue() const
{
	return value.AsString();
}

XMLNode::Names XMLNode::GetAttributes() const
{
	Names result;
	for(XMLAttributes::const_iterator it = attributes.begin(); it != attributes.end(); it++)
	{
		result.push_back(it->first);
	}
	return result;
}

const XMLValue & XMLNode::Attribute(const std::string &key) const
{
	static const XMLValue emptyValue("");
	XMLAttributes::const_iterator it = attributes.find(key);
	if(it != attributes.end())
		return it->second;
	else
		return emptyValue;
}


const XMLNode & XMLNode::Child(const std::string &key) const
{
	static const XMLNode emptyNode;
	XMLNodesMap::const_iterator it = childrenMap.find(key);
	if(it != childrenMap.end())
		return *(it->second);
	else
		return emptyNode;
}

const XMLNode & XMLNode::operator[](const std::string &key) const
{
	return Child(key);
}

const XMLNode::XMLNodes & XMLNode::Children() const
{
	return children;
}
